package com.emily.test.utils;

import com.alibaba.fastjson.JSONObject;
import com.emily.test.config.RedisSessionConfig;
import com.emily.test.model.SpringConfigurationValue;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 通用工具类
 * @author  田庆新
 */
@Component
public class ConstentUtil {
//
//    @Autowired
//    private  SpringConfigurationValue springConfigurationValue;
//
//    @Autowired
//    private RedisSessionConfig redisSessionConfig;
//
//    @Value("${spring.redis.jedis.pool.maxActive}")
//    private int maxActive;
//
//    @Value("${server.port}")
//    private int port;

    /**
     * JSONObject 转化为对象
     * @param json JSONObject 格式
     * @param pojo 相应对象
     * @return
     * @throws Exception
     */
    public static Object json2Object(JSONObject json, Class pojo) throws Exception{
        // 首先得到pojo所定义的字段
        Field [] fields = pojo.getDeclaredFields();
        // 根据传入的Class动态生成pojo对象
        Object obj = pojo.newInstance();
        for(Field field: fields){
            // 设置字段可访问（必须，否则报错）
            field.setAccessible(true);
            // 得到字段的属性名
            String name = field.getName();
            // 这一段的作用是如果字段在JSONObject中不存在会抛出异常，如果出异常，则跳过。
            try{
                json.get(name);
            }catch(Exception ex){
                continue;
            }
            if(json.get(name) != null && !"".equals(json.getString(name))){
                // 根据字段的类型将值转化为相应的类型，并设置到生成的对象中。
                if(field.getType().equals(Long.class) || field.getType().equals(long.class)){
                    field.set(obj, Long.parseLong(json.getString(name)));
                }else if(field.getType().equals(String.class)){
                    field.set(obj, json.getString(name));
                } else if(field.getType().equals(Double.class) || field.getType().equals(double.class)){
                    field.set(obj, Double.parseDouble(json.getString(name)));
                } else if(field.getType().equals(Integer.class) || field.getType().equals(int.class)){
                    field.set(obj, Integer.parseInt(json.getString(name)));
                } else if(field.getType().equals(java.util.Date.class)){
                    SimpleDateFormat sdf =   new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");
                    field.set(obj, sdf.parse(json.getString(name)));
                }else{
                    continue;
                }
            }
        }
        return obj;
    }

//    /**
//     * 获取application.yml文件中redis的配置值
//     * @return
//     */
//    public  Map<String,Object> getRedisInfo(){
//        System.out.println("maxActive======"+port);
//        if(ConstentUtil.isEmpty(springConfigurationValue)){
//            return null;
//        }
//        ObjectMapper objectMapper=new ObjectMapper();
//        Map map=springConfigurationValue.getRedis();
////        System.out.println(objectMapper.writeValueAsString(springConfigurationValue.getRedis()));
//        return springConfigurationValue.getRedis();
//    }


    /**
     * 判断是否为空
     *
     * @param o
     * @return 为空返回true，不为空返回false
     */
    public static boolean isEmpty(Object o) {
        boolean b = false;
        if (null == o || "" == o || "".equals(o)) {
            b = true;
        }
        return b;
    }

    /**
     * 判断是否为空
     *
     * @param str
     * @return 为空返回true，不为空返回false
     */
    public static boolean isEmpty(String str) {
        boolean b = false;
        if (null == str) {
            b = true;
        } else if (str.trim().length() == 0) {
            b = true;
        }
        return b;
    }

    /**
     * 判断是否为空
     *
     * @param list
     * @return 为空返回true，不为空返回false
     */
    @SuppressWarnings("unchecked")
    public static boolean isEmpty(List list) {
        boolean b = false;
        if (null == list) {
            b = true;
        } else if (list.size() == 0) {
            b = true;
        }
        return b;
    }

    /**
     * map转化为实体类
     * @param type
     * @param map
     * @return
     * @throws IntrospectionException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws InvocationTargetException
     */
    @SuppressWarnings("rawtypes")
    public static Object convertMapToObj(Class type, Map map)
            throws IntrospectionException, IllegalAccessException,
            InstantiationException, InvocationTargetException {
        BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性
        Object obj = type.newInstance(); // 创建 JavaBean 对象

        // 给 JavaBean 对象的属性赋值
        PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();
        for (int i = 0; i< propertyDescriptors.length; i++) {
            PropertyDescriptor descriptor = propertyDescriptors[i];
            String propertyName = descriptor.getName();

            if (map.containsKey(propertyName)) {
                // 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。
                Object value = map.get(propertyName);

                Object[] args = new Object[1];
                args[0] = value;

                descriptor.getWriteMethod().invoke(obj, args);
            }
        }
        return obj;
    }

    /**
     * 实体类转化为map对象
     * @param obj
     * @return
     */
    public static Map<String, Object> beanToMap(Object obj){
        if(obj==null){
            return null;
        }
        Map<String, Object> params = new HashMap<String, Object>(0);
        try {
            PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
            PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(obj);
            for (int i = 0; i < descriptors.length; i++) {
                String name = descriptors[i].getName();
                if (!"class".equals(name)) {
                    params.put(name, propertyUtilsBean.getNestedProperty(obj, name));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return params;
    }

    /**
     * List<Map<String,Object>>形式的list去重
     * @param targetMapList 要去重的List集合
     * @param mapKey 去重依据，即去重map的key的值
     * @return
     */
    public static List<Map<String,Object>> removeRepeatMap(List<Map<String,Object>> targetMapList,String mapKey){
        List<Map<String,Object>> newMapList=new ArrayList<Map<String,Object>>();
        Set<Object> mapSet=new HashSet<Object>();
        if(!ConstentUtil.isEmpty(targetMapList)){
            for(Map<String,Object> mp : targetMapList){
                Object keyValue=mp.get(mapKey);
                mapSet.add(keyValue);
            }

            for(Object setValue : mapSet){
                for(Map<String,Object> mmp : targetMapList){
                    Object mmpValue=mmp.get(mapKey);
                    if(setValue.equals(mmpValue)){
                        newMapList.add(mmp);
                        break;
                    }
                }
            }

        }
        return newMapList;
    }
}
